package edu.mama.college.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import edu.mama.college.model.*;
import edu.mama.college.service.CourseService;
import edu.mama.college.service.UserCourseService;
import edu.mama.college.service.UserStudyRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;


import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Slf4j
@RestController
public class UserCourseController {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    @Autowired
    private UserCourseService userCourseService;

    @Autowired
    private UserStudyRecordService userStudyRecordService;

    @Autowired
    private CourseService courseService;

    /**
     * 保存学习进度：记录当前用户正在学习的课程和章节
     */
    @PostMapping("/course/study/{courseId}/{lessonId}")
    public JsonResult updateUserCourse(@PathVariable int courseId,
                                       @PathVariable int lessonId,
                                       @SessionAttribute(value="user",required = false) User user){

        UserCourse userCourse = userCourseService.getUserCourse(user.getId(),courseId);
        if(userCourse == null){
            userCourse = new UserCourse();
            userCourse.setUserId(user.getId());
            userCourse.setCourseId(courseId);
            userCourse.setLessonId(lessonId);
            userCourseService.addUserCourse(userCourse);


            /**
             * 增加该课程学生人数(单元测试章节在完成)
             */
            courseService.updateStudents(courseId);
        }



        /**
         * 添加学习记录，记录用户每天每门课每个章节的学习时长（哪一天，哪门课，学习了多长时间）user_study_record
         */
//        try{
//            UserStudyRecord userStudyRecord = new UserStudyRecord(user.getId(),courseId,lessonId);
//            userStudyRecordService.insertUserStudyRecord(userStudyRecord);
//        }catch(Exception e){
//           log.info("该学生当天的的课程已经记录",e);
//        }



        return JsonResult.success();
    }

    /**
     * 更新学习时长：前端每分钟调用1次，给当前用户指定课程
     * （由请求参数courseId指定）指定章节
     * （由请求参数lessonId指定）的累计学习时长增加1分钟
     * @return
     */
    @PutMapping("/course/study/{courseId}/{lessonId}")
    public JsonResult updateUserCourseStudiedMins(
            @PathVariable int courseId,
            @PathVariable int lessonId,
            @SessionAttribute(value="user",required = false) User user){

        /**
         * 走redis缓存，这里用了redis的hash数据
         * key：`userStudyRecord::日期`，
         * field：`userID,courseId,lessonId`，
         * value：`mins`
         */
        // 当天日期
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//        String today = sdf.format(new Date());
        String today = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);

        // 线程安全（在方法中做计算操作，或类中的全局变量参与计算（所以一般全局变量都是spring容器管理的bean，不用做其他用途），或者在方法中先读取数据库再修改字段回写的时候要考虑线程安全）
        // 因为一个方法可能会被多个线程同时执行。、
        // 多个线程共享的资源包括：类的全局属性、数据库（mysql、redis、...）、硬盘文件
        /*
            String.intern()方法作用：
            调用字符串的inter()方法会首先检查字符串池中是否有这个字符串，如果存在则返回池中这个字符串的引用，否则就将这个字符串添加到字符串池中，然会返回这个字符串的引用。

            String a = new String("aaa");   内存地址F001
            String b = new String("aaa");   内存地址F002
            常量池中的"aaa"字符串              内存地址F000

            String aa = a.intern()          aa的内存地址就是F000
            String bb = b.intern()          bb的内存地址也是F000

            a.intern() 和 b.intern() 得到的是同一个对象，内存地址相同。用字符串作为同步锁，a和b是不同的锁，但是调用intern()后，则是同一把锁。
         */
        // 当前逻辑和老师的代码不一致，所以不会有线程安全问题，这里的synchronized用法只用来演示
        synchronized(("userStudyRecord::"+today).intern()){
            // 约定key的格式为`userID,courseId,lessonId`
            String id = String.valueOf(user.getId())+","+String.valueOf(courseId)+","+String.valueOf(lessonId);

            // 根据当天的日期获取hash数据
            Object mins= redisTemplate.opsForHash().get("userStudyRecord::"+today, id.toString());
            if(mins == null){
                // 如果没有则默认添加一个mins为1的数据
                redisTemplate.opsForHash().put("userStudyRecord::"+today, id.toString(), "1");
            }else{
                // 如果有则mins+1
                int intMins = Integer.parseInt( mins.toString());
                redisTemplate.opsForHash().put("userStudyRecord::"+today, id.toString(), String.valueOf(intMins+1));
            }
        }




//
//        Object cacheRecord = redisTemplate.opsForHash().get("userStudyRecord::"+date, "user_"+user.getId()+"_course_"+courseId+"_lesson_"+lessonId);
//        if(cacheRecord == null){
//            Map<String,Integer> cacheRecordMap = new HashMap<>();
//            cacheRecordMap.put("mins",1);
//            redisTemplate.opsForHash().put("userStudyRecord::"+date, "{user_id:"+user.getId()+",course_id"+courseId+",lesson_id"+lessonId+"}",cacheRecordMap);
//        }else{
//            System.out.println(cacheRecord);
//        }
//        UserCourse userCourse = userCourseService.getUserCourse(user.getId(),courseId);
//        userCourse.setLessonId(lessonId);

//        // 更新UserCourse学习时长
//        userCourseService.updateStudying(userCourse);

        // 更新userStudyRecord学习时长
//        UserStudyRecord userStudyRecord = new UserStudyRecord(user.getId(),courseId,lessonId);
//        userStudyRecordService.updateUserStudyRecord(userStudyRecord);

        return JsonResult.success();
    }

    /**
     * 我的课程分页查询
     * @param page
     * @param size
     * @return
     */
    @GetMapping("/user/course")
    public JsonResult getUserCourse(
            @RequestParam("page") int page,
            @RequestParam("size") int size,
            @SessionAttribute(value="user",required = false) User user
    ){
        int userId = user.getId();
        List<UserCourse> userCourses = userCourseService.getUserCourseList(userId,page,size);
        int total = userCourseService.getUserCourseTotal(userId);
        return JsonResult.success(new Page<>(page,size,total,userCourses));
    }



}
